import type {
  ComponentRecordType,
  GenerateMenuAndRoutesOptions,
  RouteRecordStringComponent,
} from '@vben/types';

import { h } from 'vue';
import { RouterView } from 'vue-router';

import { generateAccessible } from '@vben/access';
import { preferences } from '@vben/preferences';
import { useAccessStore, useUserStore } from '@vben/stores';

import { message } from 'ant-design-vue';

import { getCurrentUserPermissionsApi } from '#/api';
import { BasicLayout, IFrameView } from '#/layouts';
import { $t } from '#/locales';
import {
  debugMenuTransform,
  transformMenusToRoutes,
  validateMenus,
} from '#/utils/menu-transform';

const forbiddenComponent = () => import('#/views/_core/fallback/forbidden.vue');

/**
 * 从菜单树中提取菜单和按钮权限
 * @param menuTree 菜单树（包含目录、菜单、按钮）
 * @returns 提取的菜单列表和按钮权限列表
 */
function extractMenusAndPermissions(menuTree: any[]): {
  menus: any[];
  buttonPermissions: string[];
} {
  const menus: any[] = [];
  const buttonPermissions: string[] = [];

  function traverse(nodes: any[]) {
    for (const node of nodes) {
      // menuType: 1=目录, 2=菜单, 3=按钮
      if (node.menuType === 3) {
        // 按钮类型：提取权限编码
        if (node.permission) {
          buttonPermissions.push(node.permission);
        }
      } else {
        // 目录或菜单类型：添加到菜单列表
        const menuNode = { ...node };

        // 递归处理子节点
        if (node.children && node.children.length > 0) {
          const childResult = extractChildMenusAndPermissions(node.children);
          menuNode.children = childResult.menus;
          buttonPermissions.push(...childResult.buttonPermissions);
        }

        menus.push(menuNode);
      }
    }
  }

  function extractChildMenusAndPermissions(nodes: any[]): {
    menus: any[];
    buttonPermissions: string[];
  } {
    const childMenus: any[] = [];
    const childButtonPermissions: string[] = [];

    for (const node of nodes) {
      if (node.menuType === 3) {
        // 按钮类型：提取权限编码
        if (node.permission) {
          childButtonPermissions.push(node.permission);
        }
      } else {
        // 目录或菜单类型
        const menuNode = { ...node };

        // 递归处理子节点
        if (node.children && node.children.length > 0) {
          const childResult = extractChildMenusAndPermissions(node.children);
          menuNode.children = childResult.menus;
          childButtonPermissions.push(...childResult.buttonPermissions);
        }

        childMenus.push(menuNode);
      }
    }

    return {
      menus: childMenus,
      buttonPermissions: childButtonPermissions,
    };
  }

  traverse(menuTree);

  return {
    menus,
    buttonPermissions,
  };
}

async function generateAccess(options: GenerateMenuAndRoutesOptions) {
  const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue');

  const layoutMap: ComponentRecordType = {
    BasicLayout,
    IFrameView,
    // 为目录类型菜单提供 RouterView 组件
    __ROUTER_VIEW__: () => h(RouterView),
  };

  // 强制使用 backend 模式
  const accessMode = 'backend';
  console.log('🔧 当前 accessMode:', preferences.app.accessMode, '→ 强制使用:', accessMode);

  return await generateAccessible(accessMode, {
    ...options,
    // 从后端获取菜单
    fetchMenuListAsync: async () => {
      console.log('🌐 fetchMenuListAsync 被调用，准备从后端获取菜单...');
      message.loading({
        content: `${$t('common.loadingMenu')}...`,
        duration: 1.5,
      });

      try {
        // 获取用户信息
        const userStore = useUserStore();
        const accessStore = useAccessStore();
        const userId = userStore.userInfo?.userId;

        if (!userId) {
          console.error('❌ 无法获取用户ID');
          return [];
        }

        // 从后端获取用户的完整权限信息
        console.log('📡 正在获取用户权限信息，用户ID:', userId);
        console.log('📡 用户信息:', userStore.userInfo);
        console.log('🔐 [路由守卫] 当前 accessToken 状态:', {
          'token 存在': !!accessStore.accessToken,
          'token 长度': accessStore.accessToken?.length || 0,
          'token 前20字符': accessStore.accessToken?.substring(0, 20) || 'null',
        });

        let userPermissions;
        try {
          userPermissions = await getCurrentUserPermissionsApi(Number(userId));
          console.log('📋 后端返回的权限数据:', userPermissions);
          console.log('📋 权限数据类型:', typeof userPermissions);
          console.log('📋 权限数据 keys:', userPermissions ? Object.keys(userPermissions) : 'null');
        } catch (apiError: any) {
          console.error('❌ API 调用失败:', apiError);
          console.error('❌ 错误详情:', {
            message: apiError.message,
            response: apiError.response,
            stack: apiError.stack,
          });
          throw apiError;
        }

        // 检查返回数据格式并提取菜单权限
        let userMenus: any[] = [];
        let buttonPermissions: string[] = [];

        // 判断返回数据格式
        if (Array.isArray(userPermissions)) {
          console.log('✅ 检测到菜单树数组格式');

          // 从菜单树中提取菜单和按钮权限
          const extractedData = extractMenusAndPermissions(userPermissions);
          userMenus = extractedData.menus;
          buttonPermissions = extractedData.buttonPermissions;

          console.log('📋 提取的菜单数量:', userMenus.length);
          console.log('🔘 提取的按钮权限数量:', buttonPermissions.length);
          console.log('🔘 按钮权限列表:', buttonPermissions);

          // 保存按钮权限到 accessStore
          if (buttonPermissions.length > 0) {
            accessStore.setAccessCodes(buttonPermissions);
          }
        } else if (userPermissions && typeof userPermissions === 'object') {
          // 新格式：{ username, roles, menuPermissions, buttonPermissions, apiPermissions }
          if ('menuPermissions' in userPermissions) {
            console.log('✅ 检测到新格式权限数据');
            userMenus = userPermissions.menuPermissions || [];

            // 保存按钮权限到 accessStore（供页面使用）
            if (userPermissions.buttonPermissions) {
              console.log('🔘 保存按钮权限:', userPermissions.buttonPermissions);
              accessStore.setAccessCodes(userPermissions.buttonPermissions);
            }

            // 保存接口权限（打印日志，供后续使用）
            if (userPermissions.apiPermissions) {
              console.log('🔌 接口权限数量:', userPermissions.apiPermissions.length);
            }

            // 保存角色信息到 userStore
            if (userPermissions.roles) {
              console.log('👤 用户角色:', userPermissions.roles);
              // 更新用户信息中的角色
              if (userStore.userInfo) {
                userStore.userInfo.roles = userPermissions.roles;
              }
            }
          } else {
            console.warn('⚠️ 未知的权限数据格式:', userPermissions);
            console.warn('⚠️ 数据 keys:', Object.keys(userPermissions));
          }
        } else {
          console.error('❌ 权限数据为空或格式错误');
        }

        // 验证菜单数据
        const validation = validateMenus(userMenus);
        if (!validation.valid) {
          console.warn('⚠️ 菜单数据验证失败:', validation.errors);
        }

        // 将后端菜单数据转换为前端路由格式
        const routes = transformMenusToRoutes(userMenus);

        // 打印转换日志（调试用）
        if (import.meta.env.DEV) {
          debugMenuTransform(userMenus, routes);
        }

        // 根据数据格式输出不同的日志
        if (Array.isArray(userPermissions)) {
          console.log('✅ 权限加载完成（菜单树格式）:', {
            原始菜单树节点数: userPermissions.length,
            提取的菜单数量: userMenus.length,
            路由数量: routes.length,
            按钮权限数量: buttonPermissions.length,
          });
        } else if (userPermissions && 'menuPermissions' in userPermissions) {
          console.log('✅ 权限加载完成（新格式）:', {
            用户名: userPermissions.username,
            角色数量: userPermissions.roles?.length || 0,
            菜单数量: userMenus.length,
            路由数量: routes.length,
            按钮权限数量: userPermissions.buttonPermissions?.length || 0,
            接口权限数量: userPermissions.apiPermissions?.length || 0,
          });
        } else {
          console.log('✅ 菜单加载完成:', {
            菜单数量: userMenus.length,
            路由数量: routes.length,
          });
        }

        // 如果用户没有任何菜单权限，显示提示并返回空数组
        if (routes.length === 0) {
          console.warn('⚠️ 用户没有任何菜单权限');
          message.warning('您暂无任何菜单权限，请联系管理员');
          return [];
        }

        return routes;
      } catch (error) {
        console.error('❌ 获取权限失败:', error);
        message.error('获取权限失败，请重新登录');
        return [];
      }
    },
    // 可以指定没有权限跳转403页面
    forbiddenComponent,
    // 如果 route.meta.menuVisibleWithForbidden = true
    layoutMap,
    pageMap,
  });
}

export { generateAccess };
